{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "9b6ec41a",
   "metadata": {},
   "outputs": [],
   "source": [
    " '''\n",
    "     定义人类，x,y是位置。state 是人的状态，b蓝色代表未感染也没有抗体，r代表感染，g代表感染后体内存在抗体。day用于记录感染或者获得抗体的\n",
    " 天数，如假定感染后5天后自愈，获得抗体30天后，抗体消失。\n",
    "     假设每个感染者可以感染自身坐标x,y加减1内的的没有抗体的人。\n",
    " '''\n",
    "class person():  \n",
    "    x=0\n",
    "    y=0\n",
    "    state='b'\n",
    "    day=0\n",
    "    def __init__(self,x,y):\n",
    "        self.x=x\n",
    "        self.y=y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "dd9c0200",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import copy\n",
    "''' 初始化，建立一个二维数组，num*num为总人数'''\n",
    "p=[]\n",
    "num=30\n",
    "infectDay=3\n",
    "antigenDay=9\n",
    "for i in range(num):  \n",
    "    temp=[]\n",
    "    for j in range(num):\n",
    "        onePerson=person(i+1,j+1)\n",
    "        temp.append(onePerson)\n",
    "    p.append(temp)\n",
    "    \n",
    "''' 随机设定感染者'''\n",
    "for i in range(6):\n",
    "    p[np.random.randint(1, num-1)][np.random.randint(1, num-1)].state='r'\n",
    "    \n",
    "\n",
    "def infect(p,infectDay,antigenDay):\n",
    "    num=len(p)\n",
    "    temp=copy.deepcopy(p)\n",
    "\n",
    "    for i in range(num):\n",
    "        for j in range(num):\n",
    "            ''' 有抗体的人，day+1，超时，转为无抗体的人'''\n",
    "            if p[i][j].state=='g':\n",
    "                temp[i][j].day= p[i][j].day+1\n",
    "                if p[i][j].day>antigenDay:\n",
    "                    temp[i][j].day=0\n",
    "                    temp[i][j].state='b'\n",
    "                    \n",
    "            ''' 感染的人，day+1，超时，转为有抗体的人。同时感染周围没有抗体的人'''       \n",
    "            if p[i][j].state=='r':\n",
    "                temp[i][j].day= p[i][j].day+1\n",
    "                if p[i][j].day>infectDay:\n",
    "                    temp[i][j].day=0\n",
    "                    temp[i][j].state='g'\n",
    "                    \n",
    "                if i-1>=0:\n",
    "                    if p[i-1][j].state=='b':\n",
    "                        temp[i-1][j].state='r' \n",
    "                        temp[i-1][j].day=0\n",
    "                if i+1<num:\n",
    "                    if p[i+1][j].state=='b':\n",
    "                        temp[i+1][j].state='r' \n",
    "                        temp[i+1][j].day=0\n",
    "                if j-1>=0:\n",
    "                     if p[i][j-1].state=='b':\n",
    "                        temp[i][j-1].state='r' \n",
    "                        temp[i][j-1].day=0   \n",
    "                if j+1<num:\n",
    "                     if p[i][j+1].state=='b':\n",
    "                        temp[i][j+1].state='r' \n",
    "                        temp[i][j+1].day=0  \n",
    "    for i in range(20):\n",
    "        a=np.random.randint(1, num-1)\n",
    "        b=np.random.randint(1, num-1)\n",
    "\n",
    "        tempD=copy.deepcopy(temp[a][b])\n",
    "        temp[a][b]=copy.deepcopy(temp[b][a])\n",
    "        temp[b][a]=copy.deepcopy(tempD)\n",
    "    return temp\n",
    "\n",
    "\n",
    "''' 画感染图'''\n",
    "def plotInfect(p):\n",
    "    num=len(p)\n",
    "    for i in range(num): \n",
    "        for j in range(num):\n",
    "            plt.scatter(p[i][j].x, p[i][j].y,color=p[i][j].state)  \n",
    "    plt.show()\n",
    "\n",
    "def saveInfect(p,no):\n",
    "    num=len(p)\n",
    "    for i in range(num): \n",
    "        for j in range(num):\n",
    "            plt.scatter(p[i][j].x, p[i][j].y,color=p[i][j].state)  \n",
    "    plt.savefig('./img/pic-{}.png'.format(no + 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "c8a7d3e8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plotInfect(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "db0e4371",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(100):\n",
    "    p=infect(p,infectDay,antigenDay)\n",
    "    saveInfect(p,i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f65acb83",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
